package crypto

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"io"
)

const (
	AesKey = "ITAig6kWce5ia8Hr9Hj5qDP1MZyOP9DV"
)

// AesEncrypt 加密
func AesEncrypt(plaintext string) string {
	text := []byte(plaintext)
	block, err := aes.NewCipher([]byte(AesKey))
	if err != nil {
		return ""
	}

	// PKCS7 Padding
	padding := aes.BlockSize - len(text)%aes.BlockSize
	text = append(text, bytes.Repeat([]byte{byte(padding)}, padding)...)

	iv := make([]byte, aes.BlockSize)
	if _, err = io.ReadFull(rand.Reader, iv); err != nil {
		return ""
	}

	ciphertext := make([]byte, len(text))
	model := cipher.NewCBCEncrypter(block, iv)
	model.CryptBlocks(ciphertext, text)

	return base64.StdEncoding.EncodeToString(append(iv, ciphertext...))
}

// AesDecrypt 解密
func AesDecrypt(ciphertext string) string {
	data, err := base64.StdEncoding.DecodeString(ciphertext)
	if err != nil {
		return ""
	}

	block, err := aes.NewCipher([]byte(AesKey))
	if err != nil {
		return ""
	}

	if len(data) < aes.BlockSize {
		return ""
	}

	iv := data[:aes.BlockSize]
	data = data[aes.BlockSize:]
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(data, data)

	// PKCS7 Unpadding
	padding := int(data[len(data)-1])
	if padding < 1 || padding > aes.BlockSize {
		return ""
	}
	return string(data[:len(data)-padding])
}
